Editor.DraggerConnector = function () {
	var inix;
	var iniy;
	var dx;
	var dy;
	var shape;
	var impl;
	var isActive;
	var figConnector;
	var figLine;
	return {
		init: function (s) {
			shape = s;
			impl = shape.getImplementation();
			isActive = false;
		},
		mouseover: function () {
			if (!Editor.Util.isDragging()) {
				figConnector.attr(Editor.CONFIG.VISIBLE_ATTR);
			}
		},
		mouseout: function () {
			if (!Editor.Util.isDragging()) {
				figConnector.attr(Editor.CONFIG.UNVISIBLE_ATTR);
			}
		},
		remove: function () {
			figConnector.remove();
			delete figConnector;
		},
		draw: function () {
			figConnector = Editor.STATE.CANVAS.circle(0, 0, Editor.CONFIG.FIGCONNECTOR_RADIUS).attr(Editor.CONFIG.FIGCONNECTOR_ATTR);
			figConnector.translate(shape.getWidth() / 2, shape.getHeight() / 2);
			figConnector.mouseover(impl.getDraggerConnector().mouseover);
			figConnector.mouseout(impl.getDraggerConnector().mouseout);
			figConnector.mousedown(impl.getDraggerConnector().mousedown);
			figConnector.toFront();
		},
		redraw: function () {
			if (!figConnector) {
				this.draw();
			}
			var x = shape.getWidth()/2 - figConnector.getBBox().x + shape.getX() - Editor.CONFIG.FIGCONNECTOR_RADIUS;
			var y = shape.getHeight()/2 - figConnector.getBBox().y + shape.getY() - Editor.CONFIG.FIGCONNECTOR_RADIUS;
			figConnector.translate(x,y);
		},
		mousedown: function (e) {
			if (!Editor.Util.isDragging()) {
                var pos = $("#canvas").position();
				dx = e.clientX - pos.left;
				dy = e.clientY - pos.top;
				inix = dx;
				iniy = dy;

				figLine = Editor.STATE.CANVAS.path(["M", dx, dy, "L", dx, dy].join(",")).attr(Editor.CONFIG.CONNECTORRESIZE_ATTR);
				Editor.STATE.DRAGGER = impl.getDraggerConnector();
				isActive = true;
				figConnector.toFront();
			}
		},
		onmousemove: function (e) {
            var pos = $("#canvas").position();
			var dX = e.clientX - dx - pos.left;
			var dY = e.clientY - dy - pos.top;
			dx += dX;
			dy += dY;
			newPath = ["M", inix, iniy, "L", dx, dy].join(",")
			figConnector.translate(dX, dY);
			figLine.attr({
				path: newPath
			});
			figConnector.toFront();
		},
		onmouseup: function () {
      var bbox = figConnector.getBBox();
			var catched = false;
      Editor.STATE.SHAPES.forEach(function(pair) {
        if (!catched && !pair.value.isDeleted()) {
          var s = pair.value;
          if (Editor.Geometry.intersectShapes(bbox.x,bbox.y,bbox.width,bbox.height,s.getX(),s.getY(),s.getWidth(),s.getHeight())) {
						if ( (s.getTypeClass() == "resource" || s.getTypeClass() == "literal") && (s.getUuid() != impl.getUuid()) ) {
							var ax = (impl.getX()+impl.getWidth()/2)+(s.getX()+s.getWidth()/2-inix)/2;
							var ay = (impl.getY()+impl.getHeight()/2)+(s.getY()+s.getHeight()/2-iniy)/2;
							if (Editor.CONFIG.GRID_SNAP) {
								ax = Math.round(ax / Editor.CONFIG.GRID_SIZE) * Editor.CONFIG.GRID_SIZE;
								ay = Math.round(ay / Editor.CONFIG.GRID_SIZE) * Editor.CONFIG.GRID_SIZE;
							}
							
							var p;
							var cmd =  new JS.Command({
								execute: function () {
									if (this.shape != undefined) {
										this.shape.draw();
									} else {
										this.shape = Editor.Util.addProperty(ax,ay,Math.uuid(),impl.getUuid(),s.getUuid());
										p = this.shape;
									}
								},
								undo: function () {
									this.shape._remove();
								},
								stack: Editor.STATE.CMDSTACK
							});

							cmd.name = 'add property';
							cmd.execute();
							Editor.STATE.ISADDSHAPE = true;
							p.showEdit();
							catched = true;
						}
          }
        }
      });
			figLine.remove();
			delete figLine;
			var varX = dx - inix;
			var varY = dy - iniy;
			figConnector.translate(-varX, -varY);
			figConnector.attr(Editor.CONFIG.UNVISIBLE_ATTR);
			isActive = false;
			Editor.STATE.DRAGGER = undefined;
		},
		translate: function (deltaX, deltaY) {
			figConnector.translate(deltaX, deltaY);
		},
		isActive: function () {
			return isActive;
		},
		toFront: function () {
			figConnector.toFront();
		}
	}
}

